package boxe.timer.manager;

/**
 * Controller for the view mode manager 
 * 
 * @author Julien Perriard
 * @date 18.05.2010
 *
 */

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.swing.AbstractButton;
import javax.swing.DefaultListModel;

import boxe.timer.Mode;
import boxe.timer.RunPack;
import boxe.timer.env.Propertie;
import boxe.timer.view.MainWindow;
import boxe.timer.view.ModeManagerView;
import boxe.timer.view.ModeView;
import boxe.timer.view.RunView;

public class ModeManager implements ActionListener {
	/*
	 * list of elements
	 */
	private List<Mode> listMode;
	private List<RunPack> listRunPack;
	/*
	 * List model
	 */
	private DefaultListModel modeDlm;
	private DefaultListModel runDlm;
	
	private Mode currentMode;
	private Mode newMode;
	private RunPack currentRunPack;
	private RunPack newRunPack;
	private ModeView modeView;;
	private RunView runView;

	private ModeManagerView modeManagerView;
	private MainWindow mainWindow;

	/**
	 * Constructor
	 */
	public ModeManager() {
		listMode = new ArrayList<Mode>();
		listRunPack = new ArrayList<RunPack>();
		runDlm = new DefaultListModel();
		modeDlm = new DefaultListModel();
		modeView = new ModeView(this);
		runView = new RunView(this);
		modeManagerView = new ModeManagerView(this);
	}

	/**
	 * init the view
	 */
	public void initView(){
		if(currentMode != null) {
			refreshListMode();
		}
		if(currentRunPack != null){
			refreshListRun();
		}
		setSelectedIndex();
	}
	/**
	 * Add a new mode
	 * @param mode
	 */
	public void addMode(Mode mode) {
		listMode.add(mode);
	}

	/**
	 * Getter for list modes
	 * @return
	 */
	public List<Mode> getListMode() {
		return listMode;
	}
	/**
	 * Setter for list modes
	 * @return
	 */
	public void setListMode(List<Mode> listMode) {
		this.listMode = listMode;
	}
	/**
	 * add new run
	 * @return
	 */
	public void addRun(RunPack pack) {
		currentMode.getListRunPack().add(pack);;
	}

	/* 
	 * Actions listener
	 * (non-Javadoc)
	 * @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)
	 */
	public void actionPerformed(ActionEvent e) {
		String item = String.valueOf(((AbstractButton) e.getSource())
				.getActionCommand());
		/*
		 * Edit mode
		 */
		if (item.equals(Propertie.EDIT_MODE)) {
			if(currentMode == null) {
				return;
			}
			newMode = currentMode;
			modeView.setDefaultValue(currentMode);
			modeView.setVisible(true);
		} 
		
		/*
		 * new mode
		 */
		else if (item.equals(Propertie.NEW_MODE)) {
			if (modeView == null) {
				modeView = new ModeView(this);
			}
			newMode = currentMode;
			currentMode = new Mode();
			modeView.setDefaultValue(currentMode);
			modeView.setVisible(true);
			
		} 
		
		/*
		 * Cancel 
		 */
		else if (item.equals(Propertie.CANCEL)) {
			modeManagerView.setVisible(false);
		} 
		
		/*
		 * Remove mode
		 */
		else if (item.equals(Propertie.DEL_MODE)) {
			removeCurrentMode();
		} 
		
		/*
		 * Remove run
		 */
		else if (item.equals(Propertie.DEL_RUN)) {
			removeCurrentRun();
						
		} 
		
		/*
		 * Save
		 */
		else if (item.equals(Propertie.SAVE)) {
			ConfigManager conf = new ConfigManager();
			String title = "";
			if(currentMode != null) {
				 title = currentMode.getName();
				 
				if(!currentMode.getListRunPack().isEmpty()) {
					RunPack run = currentMode.getListRunPack().get(0);
					title += " : " + run.getName(); 
					long time = run.getRun().getDuration();
					SimpleDateFormat sdf = new SimpleDateFormat("mm:ss");	
					mainWindow.lblTimer.setText(sdf.format(new Date(time)));
					mainWindow.panTimer.setBackground(run.getRun().getBackground());
				}
			} 
			mainWindow.lblTitle.setText(title);
			modeManagerView.setVisible(false);
			conf.saveConfig(listMode);
		}
		/*
		 * load mode list
		 */
		else if (item.equals(Propertie.LOAD)) {
			ConfigManager conf = new ConfigManager();
			listMode = conf.loadConfig();
			refreshListMode();
		} 
		
		/*
		 * New run
		 */
		else if (item.equals(Propertie.NEW_RUN)) {
			if(currentMode == null) {
				return;
			}
			// create new run pack
			newRunPack = new RunPack();
			runView.setDefaultValue(newRunPack);
			runView.setVisible(true);
		} 
		
		/*
		 * Edit run
		 */
		else if (item.equals(Propertie.EDIT_RUN)) {
			if(currentMode == null) {
				return;
			}
			else if(!currentMode.getListRunPack().isEmpty()) {
			//Reset newRunPack
			newRunPack = null;;
			runView.setDefaultValue(currentRunPack);
			runView.setVisible(true);
			}
		}
	}

	/**
	 * Remove current mode
	 */
	private void removeCurrentMode() {
		if(currentMode != null){
			currentRunPack = null;
			int index = getModeIndex();
			getListMode().remove(currentMode);
			modeDlm.removeElementAt(index);
			if(index > 0) {
				setCurrentMode(index - 1);
			}
			if(index == 0 && !getListMode().isEmpty()){
				setCurrentMode(index);
			}
			setDefaultRunPack();
			refreshListRun();
			setSelectedIndex();
		}

	}
	
	public void setDefaultRunPack() {
		if(currentMode != null) {
			List<RunPack> runPack = currentMode.getListRunPack();
			if(!runPack.isEmpty()) {
				setCurrentRunPack(runPack.get(0));
			}
		}
	}

	/**
	 * Remove current Run
	 */
	private void removeCurrentRun() {
		if(currentRunPack != null){
			int index = getRunIndex();
			listRunPack.remove(currentRunPack);
			runDlm.removeElementAt(index);
			if(index > 0) {
				setCurrentRunPack(index - 1);
			}
			else if(index == 0 && !listRunPack.isEmpty()) {
				setCurrentRunPack(index);
			}
		}
		refreshListRun();
		setSelectedIndex();
	}
	
	/**
	 * refresh lists modes and runs
	 */
	public void refreshListMode() {
		modeDlm.clear();
		for (Mode mode : listMode) {
			modeDlm.addElement(mode.getName());
		}
	}


	/**
	 * Refresh list run 
	 */
	public void refreshListRun() {
		runDlm.removeAllElements();
		listRunPack = currentMode.getListRunPack();
		for (RunPack runPack : listRunPack) {
			runDlm.addElement(runPack.getName());
		}
	}
	
	/**
	 * Set the current list index
	 */
	public void setSelectedIndex() {
		modeManagerView.setModeListIndex(getModeIndex());
		modeManagerView.setRunListIndex(getRunIndex());
	}

	/**
	 * Get run index
	 * @return
	 */
	private int getRunIndex() {
		int index = -1;
		for(RunPack runpack : currentMode.getListRunPack()) {
			index++;
			if(currentRunPack == runpack){
				return index;
			}
		}
		return index;
	}

	/**
	 * Get index mode
	 * @return
	 */
	private int getModeIndex() {
		int index = -1;
		for(Mode mode : getListMode()) {
			index++;
			if(currentMode == mode){
				return index;
			}
		}
		return index;
	}

	/**
	 * Get dynamic mode list for JList
	 * @param index
	 */
	public DefaultListModel getModeDlm() {
		return modeDlm;
	}

	/**
	 * Set dynamic mode list for JList
	 * @param index
	 */
	public void setModeDlm(DefaultListModel modeDlm) {
		this.modeDlm = modeDlm;
	}

	/**
	 * Get dynamic run list for JList
	 * @param index
	 */
	public DefaultListModel getRunDlm() {
		return runDlm;
	}

	/**
	 * Set dynamic run list for JList
	 * @param index
	 */
	public void setRunDlm(DefaultListModel runDlm) {
		this.runDlm = runDlm;
	}
	/**
	 * Get current Mode by index
	 * @param index
	 */
	public Mode getCurrentMode() {
		return currentMode;
	}

	/**
	 * Set current Mode
	 * @param index
	 */
	public void setCurrentMode(Mode currentMode) {
		this.currentMode = currentMode;
	}

	/**
	 * Set current Mode by index
	 * @param index
	 */
	public void setCurrentMode(int index) {
		if (index >= 0) {
			setCurrentMode(listMode.get(index));
		}
	}

	/**
	 * SetCurrent RunPack  by index
	 * @param index
	 */
	public void setCurrentRunPack(int index) {
		if (index >= 0 && currentMode != null) {
			List<RunPack> runs = currentMode.getListRunPack();
			if(!runs.isEmpty()){
				currentRunPack = runs.get(index);
			}
		}
	}

	/**
	 * Setter for current runPack by runPack
	 * @param index
	 */
	public void setCurrentRunPack(RunPack runPack) {
		this.currentRunPack = runPack;
	}
	
	/**
	 * Getter for current runPack
	 * @return
	 */
	public RunPack getCurrentRunPack() {
		return currentRunPack;
	}

	/**
	 * Getter for new mode
	 * @return
	 */
	public Mode getNewMode() {
		return newMode;
	}

	/**
	 * Setter for new mode
	 * @param newMode
	 */
	public void setnewMode(Mode newMode) {
		this.newMode = newMode;
	}

	/**
	 * Getter for new runPack
	 * @return
	 */
	public RunPack getNewRunPack() {
		return newRunPack;
	}

	/**
	 * Setter for new runPack
	 * @param newRunPack
	 */
	public void setnewRunPack(RunPack newRunPack) {
		this.newRunPack = newRunPack;
	}


	/**
	 * Load config.xml file and create 
	 */
	public void loadConfig() {
		 ConfigManager confMgm = new ConfigManager();
		 List<Mode> listMode = confMgm.loadConfig();
		 setListMode(listMode);
		 if (!listMode.isEmpty() && listMode.get(0) != null) {
			 setCurrentMode(listMode.get(0));
			 if (currentMode != null && 
					 currentMode.getListRunPack().get(0) != null){
				 setCurrentRunPack(0);
			 }
			refreshListMode();
		 }
	}
	/**
	 * Getter for modeManagerView
	 * @param modeManagerView
	 */
	public ModeManagerView getView() {
		return modeManagerView;
	}

	/**
	 * Setter for modeManagerView
	 * @param modeManagerView
	 */
	public void setView(ModeManagerView modeManagerView) {
		this.modeManagerView = modeManagerView;
	}
	
	public void setTitle() {
		String modeName = currentMode.getName();
		String runName = currentRunPack.getName();
		modeManagerView.setTitle(modeName + " : " + runName);
	}

	public void setMainWindow(MainWindow mainWindow) {
		this.mainWindow = mainWindow;
		
	}
}